#ifndef _COLOR_H_
#define _COLOR_H_

#ifndef PREREQUISITES_H_
#	include "Prerequisites.h"
#endif

#include "sqplus/sqplus.h"
using namespace SqPlus;

struct Color
{
public:
	enum BlendType
	{
		BLEND_NONE = 0,
		BLEND_ALPHA,
		BLEND_ADD,
		BLEND_SUB,
		BLEND_DARKEN,
		BLEND_LIGHTEN,
		BLEND_MULTIPLY,
		BLEND_SCREEN,
		BLEND_DIFFERENCE,
		BLEND_INVERSE_DIFFERENCE,
		BLEND_INVERT,
		BLEND_DODGE
	};

public:

	Color() :
		r(0.f), g(0.f), b(0.f), a(0.f)
	{}

	inline static Color fromUint(uint32 color)
	{
		Color c;
#ifdef __BIG_ENDIAN__
		c.r = (float)((color>>24) & 0xFF)/255.f;
		c.g = (float)((color>>16) & 0xFF)/255.f;
		c.b = (float)((color>>8) & 0xFF)/255.f;
		c.a = (float)((color>>0) & 0xFF)/255.f;
#else
		c.a = (float)((color>>24) & 0xFF)/255.f;
		c.b = (float)((color>>16) & 0xFF)/255.f;
		c.g = (float)((color>>8) & 0xFF)/255.f;
		c.r = (float)((color>>0) & 0xFF)/255.f;
#endif
		return c;
	}
	inline static Color fromRGB(float red, float green, float blue)
	{
		return fromRGBA(red, green, blue, 1.f);
	}

	inline static Color fromRGBA(float red, float green, float blue, float alpha)
	{
		Color c;
		c.r = red;
		c.g = green;
		c.b = blue;
		c.a = alpha;
		return c;
	}
	inline static Color fromARGB(float alpha, float red, float green, float blue)
	{
		return fromRGBA(red, green, blue, alpha);
	}

	inline const uint32 getRGBA()
	{
#ifdef __BIG_ENDIAN__
		return ((uint32)(r * 255) << 24) | ((uint32)(g * 255) << 16)
			|((uint32)(b * 255) << 8) | (uint32)(a * 255);
#else
		return ((uint32)(a * 255) << 24) | ((uint32)(b * 255) << 16)
			|((uint32)(g * 255) << 8) | (uint32)(r * 255);
#endif
	}
	inline const uint32 getRGB()
	{
#ifdef __BIG_ENDIAN__
		return ((uint32)(r * 255) << 16) | ((uint32)(g * 255) << 8)
				| (uint32)(b * 255);
#else
		return ((uint32)(b * 255) << 16) | ((uint32)(g * 255) << 8)
				| (uint32)(r * 255);
#endif
	}

	void operator += (const Color& c)
	{
		r += c.r;
		g += c.g;
		b += c.b;
		a += c.a;
	}

	void operator -= (const Color& c)
	{
		r -= c.r;
		g -= c.g;
		b -= c.b;
		a -= c.a;
	}
	inline Color& operator = (const Color& c)
	{
		r = c.r;
		g = c.g;
		b = c.b;
		a = c.a;
		return *this;
	}
	inline Color operator + (const Color& c) const
	{
		return fromRGBA(r + c.r, g + c.g, b + c.b, a + c.a);
	}
	inline Color operator - (const Color& c) const
	{
		return fromRGBA(r - c.r, g - c.g, b - c.b, a - c.a);
	}
	inline Color operator * (const Color& c) const
	{
		return fromRGBA(r * c.r, g * c.g, b * c.b, a * c.a);
	}


	inline float* ptr()
	{
		return &r;
	}

	/** Function for writing to a stream.
	*/
	inline friend std::ostream& operator <<
		( std::ostream& o, const Color& c )
	{
		o << "Color(" << c.r << ", " << c.g << ", " << c.b << ", " << c.a << ")";
		return o;
	}

public:
	float r, g, b, a;
};

//must be declared here
DECLARE_INSTANCE_TYPE(Color)

#endif // _COLOR_H_
